package net.hn.hnms.biz.mine.service;

import org.apache.commons.lang.ArrayUtils;

import javax.xml.bind.DatatypeConverter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.*;
import java.net.InetAddress;//导入InetAddress类


/**
 * 智呈物联 pan'sx
 * 2023/2/28 11:22
 * 1.0 version
 */
public class UDPClient {
    public static void main2(String[] args) throws IOException {//主程序入口
        /*
         * 向服务器端发送数据 192.168.5.121
         */
        InetAddress address = InetAddress.getByName("localhost"); // 1.定义服务器的地址、端口号、数据
        int port = 8800;//定义端口类型
        while (true) {//通过循环不同的向客户端发送和接受数据
//            Scanner scanner = new Scanner(System.in);//从键盘接受数据
//            String send = scanner.nextLine();//nextLine方式接受字符串
//            byte[] data = send.getBytes();//将接收到的数据变成字节数组
            String[] msg = URLEncoder.encode("广播测试", "UTF-8").replaceFirst("%", "").split("%");
            byte[] bytes = "1456902".getBytes();
            String s = Integer.toHexString(1456906);
            System.out.println(s);
            byte[] data = {0x4C, 0x44, 0x49, 0x50, Byte.valueOf((Integer.toString(msg.length + 5))), 00, 00, 00, 00, 04,};

//            System.out.println(str);
//            byte[] message="广播测试";
            DatagramPacket packet = new DatagramPacket(data, data.length, address, port);//2.创建数据报，包含发送的数据信息
            DatagramSocket socket = new DatagramSocket(); // 3.创建DatagramSocket对象
            socket.send(packet);// 4.向服务器端发送数据报

            /*
             * 接收服务器端响应的数据
             */
            byte[] data2 = new byte[1024];//创建字节数组
            DatagramPacket packet2 = new DatagramPacket(data2, data2.length);// 1.创建数据报，用于接收服务器端响应的数据
            socket.receive(packet2);// 2.接收服务器响应的数据
            //3.读取数据
            String reply = new String(data2, 0, packet2.getLength());//创建字符串对象
            System.out.println("我是客户端，服务器说：" + reply);//输出提示信息
            socket.close();//4.关闭资源
        }
    }

    public static void main(String[] args) throws UnsupportedEncodingException {
        String text = "广播测试";
        String deviceId = "1456902";
        byte[] data = {0x4C, 0x44, 0x49, 0x50};//包头
        byte[] legth = {00, 00};//长度 消息ID 0+消息方向 0+消息类型 4+消息体总字节数
        byte[] mesId = {00, 00};//消息ID
        byte[] mesDirection = {00};//消息方向
        byte[] mesType = {04};//消息类型
        byte[] playType = {00};//播放类型
        byte[] devId = {00, 00, 00, 00};//设备id
        byte[] payWay = {02};//播放方式
        String[] msg = URLEncoder.encode(text, "UTF-8").replaceFirst("%", "").split("%");
        byte[] msgByte=new byte[msg.length];
        byte[] playCount = {01};//播放次数

        String id = Integer.toHexString(Integer.parseInt(deviceId));
        byte[] temp=new byte[id.length()/2];
        for (int i = 0; i < id.length(); i = i + 2) {
            temp[i / 2] = Byte.parseByte(id.substring(i, i + 2),16);
        }
        for (int i=temp.length-1;i>=0;i--){
            devId[temp.length-i-1]=temp[i];
        }
        for (int i=0;i<msg.length;i++){
            msgByte[i]=(byte) Integer.parseInt(msg[i], 16);;
        }

        byte[] msgBody = ArrayUtils.addAll(playType,devId);
        msgBody= ArrayUtils.addAll( msgBody,payWay);
        msgBody= ArrayUtils.addAll( msgBody,msgByte);
        msgBody= ArrayUtils.addAll( msgBody,playCount);
        int length=msgBody.length+4;
        String lengthStr = Integer.toHexString(length);
//        String lengthStr = "3222";
        for (int i = 0; i < lengthStr.length(); i = i + 2) {
            if(i+2<=lengthStr.length()){
                legth[i / 2] = Byte.parseByte(lengthStr.substring(i, i + 2),16);
            }else{
                legth[i / 2] = Byte.parseByte(lengthStr.substring(i, i + 1),16);
            }

        }
        data=ArrayUtils.addAll( data,legth);
        data=ArrayUtils.addAll( data,mesId);
        data=ArrayUtils.addAll( data,mesDirection);
        data=ArrayUtils.addAll( data,mesType);
        data=ArrayUtils.addAll( data,msgBody);
        int checkInt = CRC16.CRC16_MODBUS(data);
        String checkCodeStr = Integer.toHexString(checkInt);
        byte[] checkCode=new byte[checkCodeStr.length()/2];//校验码
        for (int i = 0; i < checkCodeStr.length(); i = i + 2) {
            if(i+2<=checkCodeStr.length()){
                checkCode[i / 2] = Byte.parseByte(checkCodeStr.substring(i, i + 2),16);
            }else{
                checkCode[i / 2] = Byte.parseByte(checkCodeStr.substring(i, i + 1),16);
            }

        }
        ArrayUtils.reverse(checkCode);
        data=ArrayUtils.addAll( data,checkCode);
        System.out.println(DatatypeConverter.printHexBinary(data));
    }

    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    public static byte[] fromHexString(String hexString) {
        if (null == hexString || "".equals(hexString.trim())) {
            return new byte[0];
        }

        byte[] bytes = new byte[hexString.length() / 2];// 16进制字符串 ;
        String hex;
        for (int i = 0; i < hexString.length() / 2; i++) {
// 每次截取2位
            hex = hexString.substring(i * 2, i * 2 + 2);// 16进制-->十进制
            bytes[i] = (byte) Integer.parseInt(hex, 16);
        }

        return bytes;
    }
    /**
     * 将小端bytes数据转化为大端数据
     * <p>
     * 默认网络传输字节为大端，java 全部为大端（与平台无关）
     * 关于 “Little-Endian and Big-Endian”,详情请参考：
     *
     * @param a
     * @return 转化后得到的整数
     * @Link https://howtodoinjava.com/java/basics/little-endian-and-big-endian-in-java/
     * </p>
     */
    public static byte[] changeBytes(byte[] a){
        byte[] b = new byte[a.length];
        for (int i = 0; i < b.length; i++) {
            b[i] = a[b.length - i - 1];
        }
        return b;
    }

}
